package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strings"
	"text/template"
	"unicode"
	"unicode/utf8"
)

var helpTemplate = `usage: gvt {{.UsageLine}}

{{.Long | trim}}
`

// help implements the 'help' command.
func help(args []string) {
	if len(args) == 0 {
		printUsage(os.Stdout)
		return
	}
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "usage: gvt help command\n\nToo many arguments given.\n")
		os.Exit(2)
	}

	arg := args[0]

	// 'gvt help documentation' generates alldocs.go.
	if arg == "documentation" {
		var u bytes.Buffer
		printUsage(&u)
		f, _ := os.Create("alldocs.go")
		tmpl(f, documentationTemplate, struct {
			Usage    string
			Commands []*Command
		}{
			u.String(),
			commands,
		})
		f.Close()
		return
	}

	for _, cmd := range commands {
		if cmd.Name == arg {
			tmpl(os.Stdout, helpTemplate, cmd)
			return
		}
	}

	fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run 'gvt help'.\n", arg)
	os.Exit(2)
}

var usageTemplate = `gvt, a simple go vendoring tool based on gb-vendor.

Usage:
        gvt command [arguments]

The commands are:
{{range .}}
        {{.Name | printf "%-11s"}} {{.Short}}{{end}}

Use "gvt help [command]" for more information about a command.
`

var documentationTemplate = `// DO NOT EDIT THIS FILE.
//go:generate gvt help documentation

/*
{{ .Usage }}

{{range .Commands}}{{if .Short}}{{.Short | capitalize}}
{{end}}
Usage:
        gvt {{.UsageLine}}

{{.Long | trim}}

{{end}}*/
package main
`

// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) {
	t := template.New("top")
	t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
	template.Must(t.Parse(text))
	if err := t.Execute(w, data); err != nil {
		panic(err)
	}
}

func capitalize(s string) string {
	if s == "" {
		return s
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToTitle(r)) + s[n:]
}

func printUsage(w io.Writer) {
	bw := bufio.NewWriter(w)
	tmpl(bw, usageTemplate, commands)
	bw.Flush()
}
